package com.test.zhangxin.test;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Scroller;

/**
 * Created by admin on 2017/6/7.
 */

public class MyView extends ViewGroup {
    private final int mMinimumVelocitX;
    private final int mTouchSlop;
    private int[] mImgs;
    private GestureDetector mDetector;
    private Scroller mScroller;
    private float mTransformPos;
    private float minAlpha = 0.5f;
    private float maxScale = 0.8f;
    private float maxRotatX = 10f;
    private float maxRotatY = 20f;
    private int mWidth;
    private float mStartX;
    private int mCurrentScreenIndex;
    private boolean isFling;

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setStaticTransformationsEnabled(true);
        mImgs = new int[]{R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d};
        setFocusable(true);
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        setWillNotDraw(false);
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
        mMinimumVelocitX = configuration.getScaledMinimumFlingVelocity();

        initView();
    }

    public void setImgs(int[] data) {
        if (data == null)
            throw new NullPointerException("图片资源不能为空哦");
        else mImgs = data;
    }

    private void initView() {
        for (int i = 0; i < mImgs.length; i++) {
            ImageView iv = new ImageView(getContext());
            iv.setBackgroundResource(mImgs[i]);
            this.addView(iv);
        }
        mDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                float distance = e1.getX() - e2.getX();
                if ((mCurrentScreenIndex == 0 && distance < 0) || (mCurrentScreenIndex == mImgs.length - 1 && distance > 0)) {
                    return false;
                }
                scrollBy((int) distanceX, 0);
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                float distance = Math.abs(e1.getX() - e2.getX());
                //惯性滑动
                if (distance < mWidth / 3) {
                    isFling = false;
                } else if (Math.abs(velocityX) > mMinimumVelocitX) {
                    Log.e("zx", "onfling");
                    isFling = true;
                    mScroller.fling(getScrollX(), getScrollY(), (int) -velocityX, 0, 0, (mImgs.length - 1) * mWidth, 0, 0);
                    awakenScrollBars(mScroller.getDuration());
                    int finalX = mScroller.getFinalX();
                    scrollToScreen((finalX + (getWidth() / 2)) / getWidth());
                }
                isFling = false;
                return true;
            }
        });
        mScroller = new Scroller(getContext());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measureHeigth = MeasureSpec.getSize(heightMeasureSpec);
        int pWidtMode = MeasureSpec.getMode(widthMeasureSpec);
        int pHeightSMode = MeasureSpec.getMode(heightMeasureSpec);
        View child = getChildAt(0);
        //测量子类
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        //获取第一个子View的宽高作为默认值
        int width = child.getMeasuredWidth();
        int height = child.getMeasuredHeight();

        //处理wrap-content的情况
        if (pWidtMode == MeasureSpec.AT_MOST && pHeightSMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, height);
        } else if (pWidtMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, measureHeigth);
        } else if (pHeightSMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(measureWidth, height);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mWidth = getWidth();
        for (int i = 0; i < getChildCount(); i++) {
            View child = this.getChildAt(i);
            if (child.getVisibility() != GONE) {
                child.layout(i * mWidth, t, (i + 1) * mWidth, b);
                //初始化动画
                mTransformPos = (float) (child.getLeft() - getScrollX()) / getClientWidth();
                doAnimate(child, mTransformPos);
            }
        }
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //滚动改变做动画
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            mTransformPos = (float) (child.getLeft() - getScrollX()) / getClientWidth();
            doAnimate(child, mTransformPos);
        }
    }

    private void doAnimate(View child, float position) {
        if (position <= -1) {//(负无穷,-1]图片居左的情况
            ViewCompat.setRotationY(child, maxRotatY);
            ViewCompat.setRotationX(child, maxRotatX);
            ViewCompat.setPivotX(child, 0);
            ViewCompat.setAlpha(child, minAlpha);
            ViewCompat.setScaleY(child, maxScale);
        } else if (position <= 1) {//[-1,1]
            child.setRotationY(-position * maxRotatY);
            if (position <= 0) {//[-1,0]图片向左的情况
                child.setRotationX(-position * maxRotatX);
                ViewCompat.setPivotX(child, 0);
                ViewCompat.setAlpha(child, 1 + position * (1 - minAlpha));
                ViewCompat.setScaleY(child, 1 + position * (1 - maxScale));
            } else {//(0,1]//图片向右的情况
                child.setRotationX(position * maxRotatX);
                ViewCompat.setPivotX(child, child.getWidth());
                ViewCompat.setAlpha(child, 1 - position * (1 - minAlpha));
                ViewCompat.setScaleY(child, 1 - position * (1 - maxScale));
            }
        } else {//[1,正无穷)图片居右的情况
            ViewCompat.setRotationY(child, -maxRotatY);
            ViewCompat.setRotationX(child, maxRotatX);
            ViewCompat.setPivotX(child, child.getWidth());
            ViewCompat.setAlpha(child, minAlpha);
            ViewCompat.setScaleY(child, maxScale);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDetector.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                mStartX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                float endX = event.getX();
                if (!isFling) {
                    Log.e("zx", "onTouch");
                    if (endX - mStartX > mWidth / 6)
                        scrollToScreen(mCurrentScreenIndex - 1);
                    else if (mStartX - endX > mWidth / 6)
                        scrollToScreen(mCurrentScreenIndex + 1);
                    else
                        snapToDestination();
                }
                break;
        }
        return true;
    }

    /**
     * 切换到指定屏
     *
     * @param whichScreen
     */
    public void scrollToScreen(int whichScreen) {
        if (whichScreen >= mImgs.length)
            whichScreen = mImgs.length - 1;
        else if (whichScreen <= 0)
            whichScreen = 0;
        if (getFocusedChild() != null && whichScreen != mCurrentScreenIndex && getFocusedChild() == getChildAt(mCurrentScreenIndex)) {
            getFocusedChild().clearFocus();
        }
        final int delta = whichScreen * getWidth() - getScrollX();
        mScroller.startScroll(getScrollX(), 0, delta, 0, 500);
        invalidate();
        mCurrentScreenIndex = whichScreen;
    }

    /**
     * 根据当前x坐标位置确定切换到第几屏
     */
    private void snapToDestination() {
        scrollToScreen((getScrollX() + (getWidth() / 2)) / getWidth());
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), 0);
            postInvalidate();
        }
    }

    public float getClientWidth() {
        return getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    }
}
